IE中的XSTL

它不是一种正式的规范,, 是XPath的另一表现形式。 IE是第一个支持它的。

简单的XSTL转换

XML文档的方式就是将它们分别加到一个DOM文档中, 然后使用

  • transformNode()

方法。

这个方法接收一个参数, 即包含XSTL样式表的文档。 调用这个方法之后会返回一个包含转换信息的字符串。

xmldom.load("employees.xml");
xstldom.load("employees.xstl");
var result = xmldom.transformNodes(xstldom);

这个transformNode的参数可以是XML文档的DOM节点。 如果不是在文档元素上调用transformNode, 那么转换就会从调用节点上开始。

复杂的XSLT转换

要使用复杂的XSTL转换, 必须使用XSL模板和XSL处理器。 先要把XSTL样式表加载到一个线程安全的XML文档中。

function createThreadSafeDocument() {
    if (typeof arguments.callee.activeXString != "string") {
        var versions = ["MSXML2.FreeThreadedDOMDocument.6.0", "MSXML2.FreeThreadedDOMDocument.3.0", "MSXML2.FreeThreadedDOMDocument"],
            i, len;
        for (i = 0, len = versions.length; i < len; i++) {
            try {
                new ActiveXObject(versions[i]);
                arguments.callee.activeXString = versions[i];
                break;
            } catch (ex) {
                //skip   
            }
        }
    }
    return new ActiveXObject(arguments.callee.activeXString);
}

创建XSTL模板:

function createXSTLTemplate() {
    if (typeof arguments.callee.activeXString != "string") {
        var versions = ["MSXML2.FreeThreadedDOMDocument.6.0", "MSXML2.FreeThreadedDOMDocument.3.0", "MSXML2.FreeThreadedDOMDocument"],
            i, len;
        for (i = 0, len = versions.length; i < len; i++) {
            try {
                new ActiveXObject(versions[i]);
                arguments.callee.activeXString = versions[i];
                break;
            } catch (ex) {
                //skip    
            }
        }
    }
    return new ActiveXObject(arguments.callee.activeXString);
}

下面是使用示例:

var xsltdom = createThreadSafeDocument();
xstldom.async = false;
xsltdom.load("employees.xslt");

var template = createXSTLTemplate();
template.stylesheet = xstldom;

var processor = tempalte.createProcessor();
processor.input = xmldom;
processor.transform();
var result = processor.output;

在创建了XSL处理器之后, 必须将要转换的节点指定给input属性。 这个值可以是一个文档, 也可以是文档的任何节点。 然后调用transform方法即可执行转换并将结果作为字符串保存在output属性中。 这些代码实现了transformNode相同的功能。 使用XSL处理器可以对转换进行更多的控制, 同时也支持更高级的XSTL特性。

要将样式表中的参数进行赋值处理, 可以使用addParaneter() 方法, 它接收两个参数: 要设置的参数名称和要指定的值。

processor.input = xmldom.documentElement;
processor.addParameter("message", "Hello wrold!");
processor.transform();

XSL处理器的另一个高级特性是能够设置一种操作模式。 在XSTL中, 可以使用mode特性为模板定义一种模式在定义了模式之后, 如果没有将 < xsl: apply - tempaltes > 与匹配的mode特性一起使用, 就不会运行该模板。 如果在 < xsl: apply - tempaltes > 元素的模式设置为“ title - first”, 那么在javascript使用时就需要像下面这样进行设置:

processor.input = xmldom;
processor.addParameter("message", "Hello wrold!");
processor.setStartMode("title-first");
processor.transform();

如果打算用一个XSTL样式表进行多次转换, 可以在每次转换之后调用reset() 方法重置处理器。

processor.reset();

因为处理器已经编译了XSTL样式表, 与transformNode() 相比, 这样的转换速度会更快一些

XSLTProcessor类型

Mozilla通过火狐创建新类型, 其他非IE浏览器借鉴了它, 也实现了这个类型。 主要的功能是用来将XSLT转换为XML文档。

第一步加载DOM文档, 一个基于XML, 另一个基于XSLT。 然后创建一个新XSLTProceesor对象, 并使用importStylesheet() 方法为其指定一个XSLT。 示例:

var processor = new XSLTProcessor();
processor.importStylesheet(xsltdom);

最后一步是执行转换。 这一步有两种不同的方式: 如果想返回一个完整的DOM文档, 可以调用

  • transformToDocument()

如果想返回一个文档片段, 可以使用

  • transformToFragment()

transformToDocument() 的参数是一个XML DOM。 transformToFragment() 的参数有两个, 第一个是XML DOM, 第二个是拥有该文档片段的文档。

  • setParameter() 方法可以用来设置XSLT的参数, 该方法接收三个参数: 命名空间URI, 参数的内部名称和要设置的值。 这个方法必须在进行最后一步转化之前调用。

  • getParameter() 方法用于取得当前参数的值, 参数为命名空间URI和参数的内部名称。

  • removeParameter() 方法用于移除当前参数的值, 参数为命名空间URI和参数的内部名称。

后面两个方法并不常用, 提供他们只是为了方便。

重置处理器的方法是reset() 方法。

跨浏览器使用XSLT

function transform(context, xslt) {
    if (typeof XSLTProcessor != "undefined") {
        var processor = new XSLTProcessor();
        processor.importStylesheet(xslt);
        var result = processor.transformToDocument(context);
        return (new XMLSerializer()).serializeToString(result);
    } else if (typeof context.transformNode != "undefined") {
        return caontext.transformNode(xslt);
    } else {
        throw new Error("No XSLT processor available.");
    }
}

这个函数接收两个参数: 要执行转换的上下文节点和XSLT文档对象。 返回序列化之后的字符串。


var result = transform(xmldom, xsltdom);

JS菌
6.4k 声望2k 粉丝